//
//  UIView+Extensions.swift
//  DevelopmentPods
//
//  Created by 尹琼 on 2022/10/25.
//

import UIKit



// MARK - frame extensions
public extension UIView {
    
    // x
    var x : CGFloat {
        
        get {
            
            return frame.origin.x
        }
        
        set(newVal) {
            
            var tmpFrame : CGRect = frame
            tmpFrame.origin.x     = newVal
            frame                 = tmpFrame
        }
    }
    
    // y
    var y : CGFloat {
        
        get {
            
            return frame.origin.y
        }
        
        set(newVal) {
            
            var tmpFrame : CGRect = frame
            tmpFrame.origin.y     = newVal
            frame                 = tmpFrame
        }
    }
    
    // height
    var height : CGFloat {
        
        get {
            
            return frame.size.height
        }
        
        set(newVal) {
            
            var tmpFrame : CGRect = frame
            tmpFrame.size.height  = newVal
            frame                 = tmpFrame
        }
    }
    
    // width
    var width : CGFloat {
        
        get {
            
            return frame.size.width
        }
        
        set(newVal) {
            
            var tmpFrame : CGRect = frame
            tmpFrame.size.width   = newVal
            frame                 = tmpFrame
        }
    }
    
    // left
    var left : CGFloat {
        
        get {
            
            return x
        }
        
        set(newVal) {
            
            x = newVal
        }
    }
    
    // right
    var right : CGFloat {
        
        get {
            
            return x + width
        }
        
        set(newVal) {
            
            x = newVal - width
        }
    }
    
    // top
    var top : CGFloat {
        
        get {
            
            return y
        }
        
        set(newVal) {
            
            y = newVal
        }
    }
    
    // bottom
    var bottom : CGFloat {
        
        get {
            
            return y + height
        }
        
        set(newVal) {
            
            y = newVal - height
        }
    }
    
    var centerX : CGFloat {
        
        get {
            
            return center.x
        }
        
        set(newVal) {
            
            center = CGPoint(x: newVal, y: center.y)
        }
    }
    
    var centerY : CGFloat {
        
        get {
            
            return center.y
        }
        
        set(newVal) {
            
            center = CGPoint(x: center.x, y: newVal)
        }
    }
    
    var middleX : CGFloat {
        
        get {
            
            return width / 2
        }
    }
    
    var middleY : CGFloat {
        
        get {
            
            return height / 2
        }
    }
    
    var middlePoint : CGPoint {
        
        get {
            
            return CGPoint(x: middleX, y: middleY)
        }
    }
}



public extension UIView {

    class func loadNib<T: UIView>(_ viewType: T.Type) -> T {
        let className = String.className(viewType)
        return Bundle(for: viewType).loadNibNamed(className, owner: nil, options: nil)!.first as! T
    }
    
    class func loadNib() -> Self {
        return loadNib(self)
    }
}

// MARK:------关于Cell的扩展
public extension UITableViewCell {

    static var reuseIdentifier: String {
        return String(describing: self)
    }

    static var xnib: UINib {
        return UINib(nibName: reuseIdentifier, bundle: nil)
    }
}

public extension UICollectionReusableView {

    static var reuseIdentifier: String {
        return String(describing: self)
    }

    static var xnib: UINib {
        return UINib(nibName: reuseIdentifier, bundle: nil)
    }
}

public extension UITableViewHeaderFooterView {

    static var reuseIdentifier: String {
        return String(describing: self)
    }

    static var xnib: UINib {
        return UINib(nibName: reuseIdentifier, bundle: nil)
    }
    
}
// MARK: - Methods


 
public extension UIView {
    
    func superview<T>(of type: T.Type) -> T? {
        return superview as? T ?? superview.flatMap { $0.superview(of: T.self) }
    }
    
     func searchVisualEffectsSubview() -> UIVisualEffectView? {
        if let visualEffectView = self as? UIVisualEffectView {
            return visualEffectView
        } else {
            for subview in subviews {
                if let found = subview.searchVisualEffectsSubview() {
                    return found
                }
            }
        }
        return nil
    }
    
    /// This is the function to get subViews of a view of a particular type
    /// https://stackoverflow.com/a/45297466/5321670
    func subViews<T : UIView>(type : T.Type) -> [T]{
        var all = [T]()
        for view in self.subviews {
            if let aView = view as? T{
                all.append(aView)
            }
        }
        return all
    }
    
    
    /// This is a function to get subViews of a particular type from view recursively. It would look recursively in all subviews and return back the subviews of the type T
    /// https://stackoverflow.com/a/45297466/5321670
    func allSubViewsOf<T : UIView>(type : T.Type) -> [T]{
        var all = [T]()
        func getSubview(view: UIView) {
            if let aView = view as? T{
                all.append(aView)
            }
            guard view.subviews.count>0 else { return }
            view.subviews.forEach{ getSubview(view: $0) }
        }
        getSubview(view: self)
        return all
    }
    
    /// 删除所有的子视图
    func removeAllSubViews() {
        subviews.forEach { (view) in
            view.removeFromSuperview()
        }
    }
    
    var viewController: UIViewController? {
        var nextResponder = self.next
        while nextResponder != nil {
            if nextResponder!.isKind(of: NSClassFromString("UIViewController")!) {
                let vc = nextResponder as? UIViewController
                return vc
            }
            nextResponder = nextResponder?.next
        }
        return nil
    }
    
    var navigationBar: UINavigationBar? {
        viewController?.navigationController?.navigationBar
    }
}


public extension UIView {
    
    struct Corners: OptionSet {
        public let rawValue: Int
        
        public init(rawValue: Int) {
            self.rawValue = rawValue
        }
        
        static let topLeft = Corners(rawValue: 1 << 0)
        static let topRight = Corners(rawValue: 1 << 1)
        static let bottomLeft = Corners(rawValue: 1 << 2)
        static let bottomRight = Corners(rawValue: 1 << 3)

        public static let top: Corners = [.topLeft, .topRight]
        public static let bottom: Corners = [.bottomLeft, .bottomRight]
        public static let left: Corners = [.topLeft, .bottomLeft]
        public static let right: Corners = [.topRight, .bottomRight]

        public static let all: Corners = [.topLeft, .topRight, .bottomLeft, .bottomRight]
    }
    /// 设置圆角
    /// - Parameters:
    ///   - corners: 圆角位置
    ///   - radius: 圆角大小
    func setRoundedCorners(_ corners: Corners, radius: CGFloat) {
        var masks = CACornerMask()
        if corners.contains(.topLeft) {
            masks.insert(.layerMinXMinYCorner)
        }
        if corners.contains(.topRight) {
            masks.insert(.layerMaxXMinYCorner)
        }
        if corners.contains(.bottomLeft) {
            masks.insert(.layerMinXMaxYCorner)
        }
        if corners.contains(.bottomRight) {
            masks.insert(.layerMaxXMaxYCorner)
        }
        if #available(iOS 11.0, *) {
            layer.maskedCorners = masks
        } else {
            // Fallback on earlier versions
        }
        layer.cornerRadius = radius
        layer.masksToBounds = true
    }
    /// 快速设置圆角
    /// - Parameter cornerRadius: 圆角
    func setFastCorners(_ cornerRadius: CGFloat) {
        layer.cornerRadius = cornerRadius
        layer.masksToBounds = true
    }
}

public extension UIView {
    
    /// 抖动方向枚举
    enum ShakeDirection: Int {
        /// 水平抖动
        case horizontal
        /// 垂直抖动
        case vertical
    }
    
    /// 竖虚线
    /// - Parameter lineNumber: 条数
    func drawDottedLine(lineNumber : Int, lineColor:UIColor) {
        
        let height = (self.frame.height-1) / CGFloat(lineNumber)
        self.removeAllSubViews()
        for i in 0...lineNumber{
             let lineView = UIView()
             self.addSubview(lineView)
             let topSpace = height * CGFloat(i)
             lineView.snp.makeConstraints { make in
                 make.top.equalTo(topSpace)
                 make.leading.trailing.equalToSuperview()
                 make.height.equalTo(1)
             }
            lineView.layoutIfNeeded()
            lineView.drawDashLine(strokeColor: lineColor ,direction: .horizontal)
         }
    }
    
    /// 绘制虚线
    /// - Parameters:
    ///   - strokeColor: 虚线颜色
    ///   - lineWidth: 虚线宽度
    ///   - lineLength: 每段虚线的长度
    ///   - lineSpacing: 每段虚线的间隔
    ///   - lineTop: 垂直方向距离头部距离
    ///   - width: 水平方向宽度及X轴间距
    func drawDashLine(strokeColor: UIColor,
                             lineWidth: CGFloat = 1,
                             lineLength: Int = 6,
                             lineSpacing: Int = 4,
                             lineTop : CGFloat = 0,
                             width : CGFloat = 0,
                             direction: ShakeDirection = .vertical){
        let shapeLayer = CAShapeLayer()
        if direction == .vertical {
            shapeLayer.bounds = bounds
            shapeLayer.position = CGPoint(x: 0, y: frame.height / 2)
        }else{
            shapeLayer.bounds = CGRect(x: 0, y: 0, width: frame.width, height: 2)
            shapeLayer.position = CGPoint(x: frame.width / 2, y:lineTop)
        }
        shapeLayer.fillColor = UIColor.blue.cgColor
        shapeLayer.strokeColor = strokeColor.cgColor
        
        shapeLayer.lineWidth = lineWidth
        shapeLayer.lineJoin = CAShapeLayerLineJoin.round
        shapeLayer.lineDashPhase = 0
        /// 每一段虚线长度 和 每两段虚线之间的间隔
        shapeLayer.lineDashPattern = [NSNumber(value: lineLength),
                                      NSNumber(value: lineSpacing)]
        
        let path = CGMutablePath()
        if direction == .vertical {
            /// 起点
            path.move(to: CGPoint(x: frame.width / 2, y: 0))
            /// 终点
            path.addLine(to: CGPoint(x: frame.width / 2, y: frame.height))
        }else{
            /// 起点
            path.move(to: CGPoint(x: 0, y: 0))
            /// 终点
            path.addLine(to: CGPoint(x: frame.width, y: 0))
        }
        shapeLayer.path = path
        layer.addSublayer(shapeLayer)
    }
}


public extension UIView {
    func addOnClickListener(target: AnyObject, action: Selector) {
        let gr = UITapGestureRecognizer(target: target, action: action)
        gr.numberOfTapsRequired = 1
        isUserInteractionEnabled = true
        addGestureRecognizer(gr)
    }
    
    func screenShot() -> UIImage? {
        guard frame.size.height > 0 && frame.size.width > 0 else {
            return nil
        }
        UIGraphicsBeginImageContextWithOptions(frame.size, false, 0)
        layer.render(in: UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return image
    }
}

